package com.plian.system.service.fr.bulletin;

import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.common.status.CustomCode;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.dao.fr.bulletin.BulletinDao;
import com.plian.system.dao.sys.orgzation.OrgzationDao;
import com.plian.system.listener.BulletinEvent;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.page.Page;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.orgzation.OrgzationService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.vo.fr.bulletin.BulletinSummaryDetailVO;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.FormStatusConstant.*;
import static com.plian.system.constant.sys.FormTypeConstant.FR_BULLETIN;

@Service
public class BulletinService implements BaseFlowService {
    @Autowired
    private BulletinDao bulletinDao;

    @Autowired
    private OrgzationDao orgzationDao;

    @Autowired
    private OrgzationService orgzationService;

    @Autowired
    private FormWorkflowService formWorkflowService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private IBulletinSummaryRelationService bulletinSummaryRelationService;

    @Autowired
    private IOrgService orgService;

    /**
     * logger属性.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(BulletinService.class);


    /*
    保存
    */
    public ObjResult save(PageData pd) {
        ObjResult objResult;
        PageData pdd = new PageData();
        PageData oldPdd = new PageData();
        try {
            String year = pd.getString("reportTime").substring(0, 4);
            String month = pd.getString("reportTime").substring(5, 7);
            if (Tools.notEmpty(pd.getString("id"))) {
                pd.put("reportTime", year + "-" + month + "-01");
                pdd.putAll(pd);
                for (Object key : pdd.keySet()) {
                    if (null != pdd.getString(key)) {
                        if ("".equals(pdd.getString(key))) {
                            pdd.put(key, null);
                        }
                    }
                }
                oldPdd = bulletinDao.findById(pd);
                pdd.put("orgId", oldPdd.getString("orgId"));
                bulletinDao.edit(pdd);
            } else {
                pdd.putAll(pd);
                pdd.put("id", UuidUtil.get32UUID());
                pdd.put("orgId", TokenUtil.getTokenOrgId());
                pdd.put("reportTime", year + "-" + month + "-01");
                pdd.put("formType", FormTypeConstant.FR_BULLETIN);
                pdd.put("status", "0");
                for (Object key : pdd.keySet()) {
                    if (null != pdd.getString(key)) {
                        if ("".equals(pdd.getString(key))) {
                            pdd.put(key, null);
                        }
                    }
                }
                bulletinDao.save(pdd);

            }
            List<String> childIds = (List<String>)pd.get("childIds");
            if (CollectionUtil.isNotEmpty(childIds)){
                bulletinSummaryRelationService.submit(pdd.getString("id"), childIds);
            }
            List<PageData> list = new ArrayList<>();
            list.add(oldPdd);
            list.add(pdd);
            applicationContext.publishEvent(new BulletinEvent(list));
            objResult = new ObjResult(CommonCode.SUCCESS);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
            return objResult;
        }
        HashMap<String, Object> processVariable = new HashMap<>();
        formWorkflowService.startProcessAndSimulate(pdd.getString("id"), pdd.getString("formType"), processVariable);
        return objResult;
    }

    /**
     * 初始化报表
     *
     * @param
     * @throws Exception
     */
    public ObjResult originReport(PageData pd) {
        ObjResult objResult;
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            if (pd.get("reportTime") == null) {
                objResult = new ObjResult(CommonCode.NORMAL);
                objResult.setMessage("请先选择填报时间");
            } else {
                pd.put("reportTime", pd.getString("reportTime") + "-01");
            }
            PageData org = orgzationDao.findbyid(pd.getString("orgId"));
            List<PageData> parentList = new ArrayList<>();
            orgzationService.getParentList(org.getString("parentId"), parentList);
            String formTypeCode[] = {"0", "1", "6"};
            String formTypeCode2[] = {"1", "6"};
            PageData report = new PageData();
            int summaryCode = parentList.size();
            int isExist = 0;
            String tablename = "";
            switch (orgzationDao.findbyid(pd.getString("orgId")).getString("typeCode")) {
                case "0":
                    for (int i = 0; i < formTypeCode.length; i++) {
                        pd.put("tableTypeCode", formTypeCode[i]);
                        if ("6".equals(formTypeCode[i])) {
                            pd.put("summaryCode", summaryCode - 1);
                        } else {
                            pd.put("summaryCode", summaryCode);
                        }
                        report = bulletinDao.findByDate(pd);
                        if (report == null) {
                            save(pd);
                        } else {
                            if ("6".equals(formTypeCode[i])) {
                                isExist = 1;
                            } else {
                                if ("6".equals(formTypeCode[i])) {
                                    tablename += "“集团合并表”、";
                                    isExist = 1;
                                } else if ("1".equals(formTypeCode[i])) {
                                    tablename += "“差额表”、";
                                    isExist = 1;
                                } else {
                                    tablename += "“单户表”、";
                                    isExist = 1;
                                }
                            }
                        }
                    }
                    break;
                case "1":
                    pd.put("tableTypeCode", "0");
                    pd.put("summaryCode", summaryCode - 1);
                    report = bulletinDao.findByDate(pd);
                    if (report == null) {
                        save(pd);
                    } else {
                        isExist = 1;
                    }
                    break;
                case "2":
                    pd.put("tableTypeCode", "0");
                    pd.put("summaryCode", summaryCode);
                    report = bulletinDao.findByDate(pd);
                    if (report == null) {
                        save(pd);
                    } else {
                        isExist = 1;
                    }
                    break;
                case "3":
                    for (int i = 0; i < formTypeCode.length; i++) {
                        pd.put("tableTypeCode", formTypeCode[i]);
                        if ("6".equals(formTypeCode[i])) {
                            pd.put("summaryCode", summaryCode);
                        } else {
                            pd.put("summaryCode", summaryCode + 1);
                        }
                        report = bulletinDao.findByDate(pd);
                        if (report == null) {
                            save(pd);
                        } else {
                            if ("6".equals(formTypeCode[i])) {
                                tablename += "“集团合并表” ";
                                isExist = 1;
                            } else if ("1".equals(formTypeCode[i])) {
                                tablename += "“差额表” ";
                                isExist = 1;
                            } else {
                                tablename += "“单户表” ";
                                isExist = 1;
                            }
                        }
                    }
                    for (int i = 0; i < formTypeCode2.length; i++) {
                        pd.put("tableTypeCode", formTypeCode2[i]);
                        if ("6".equals(formTypeCode2[i])) {
                            pd.put("summaryCode", summaryCode - 1);
                        } else {
                            pd.put("summaryCode", summaryCode);
                        }
                        report = bulletinDao.findByDate(pd);
                        if (report == null) {
                            save(pd);
                        } else {
                            if ("6".equals(formTypeCode[i])) {
                                tablename += "“集团合并表(分公司)” ";
                                isExist = 1;
                            } else if ("1".equals(formTypeCode[i])) {
                                tablename += "“差额表(分公司)” ";
                                isExist = 1;
                            } else {
                                tablename += "“单户表” ";
                                isExist = 1;
                            }
                        }
                    }
                    break;
                default:
                    break;
            }

            if (isExist == 0) {
                objResult = new ObjResult(CommonCode.SUCCESS);
                objResult.setPageData(pd);
            } else {
                objResult = new ObjResult(CommonCode.NORMAL);
                objResult.setMessage("已存在本年度" + tablename + ",其余表新建成功");
            }
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
            return objResult;
        }
        return objResult;
    }

    /**
     * 删除
     */
    public ObjResult delete(PageData pd) {
        ObjResult objResult;
        try {
            PageData bull = bulletinDao.findById(pd);
            bulletinDao.delete(bull);
            List<String> ids = new ArrayList<>();
            ids.add(bull.getString("id"));
            for (String id : ids) {
                formWorkflowService.deleteProcessInstance(id);
            }
            bulletinSummaryRelationService.deleteByBaseId(ids);
            objResult = new ObjResult(CommonCode.SUCCESS);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
            return objResult;
        }
        return objResult;
    }

    /*
     * 列表
     * */
    public ListResult<PageData> listPage(PageData pd) {
        try {
            if (Tools.isEmpty(pd.getString("orgId"))) {
                pd.put("orgId", TokenUtil.getTokenOrgId());
            }
            List<PageData> list = new ArrayList<>();
            List<PageData> orgList = orgzationService.getSubordinate().getList();
            if (CollectionUtil.isEmpty(orgList)) {
                return new ListResult<>(CustomCode.builder().message("企业树初始化失败").code(1999).success(false).build());
            }
            Page page = new Page(true, pd);
            if (pd.getString("summary") != null) {
                list = getListTree(orgList, pd);
            } else {
                list = getList(pd);
            }
            int pageTotal = (page.getPageNumber() - 1) * page.getPageSize();
            int pageTotal1 = page.getPageNumber() * page.getPageSize();
            ListResult<PageData> Result = new ListResult<>(CommonCode.SUCCESS);
            if (list.size() < pageTotal1) {
                Result.setList(list.subList(pageTotal, list.size()));
            } else {
                Result.setList(list.subList(pageTotal, pageTotal1));
            }
            Result.setTotal(list.size());
            return Result;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ListResult<>(CommonCode.ERROR);
        }
    }

    public List<PageData> getList(PageData pd) throws Exception {
        PageData orgpd = orgzationDao.findbyid(pd.getString("orgId"));
        List<PageData> list = new ArrayList<>();
        List<PageData> parentList = new ArrayList<>();
        switch (orgpd.getString("typeCode")) {
            case "0":
                list = findlist(orgpd.getString("id"), "", "6");
                for (PageData p : list) {
                    p.put("hasChild", true);
                }
                break;
            case "1":
                list = findlist(orgpd.getString("id"), "", "0");
                break;
            case "2":
                list = findlist(orgpd.getString("id"), "", "0");
                break;
            case "3":
                orgzationService.getParentList(orgpd.getString("parentId"), parentList);
                int summaryCode = parentList.size();
                if (Tools.isEmpty(pd.getString("reportTime"))) {
                    list = findlist(orgpd.getString("id"), "", "6", summaryCode - 1);
                } else {
                    list = findlist(orgpd.getString("id"), pd.getString("reportTime"), "6", summaryCode - 1);
                }
                for (PageData p : list) {
                    p.put("hasChild", true);
                }
                break;
            default:
                break;

        }

        return list;
    }

    public ListResult<PageData> treeList(PageData pd) {
        try {
            if (Tools.isEmpty(pd.getString("orgId"))) {
                pd.put("orgId", TokenUtil.getTokenOrgId());
            }
            List<PageData> list = new ArrayList<>();
            List<PageData> orgList = orgzationService.getSubordinate().getList();
            if (CollectionUtil.isEmpty(orgList)) {
                return new ListResult<>(CustomCode.builder().message("企业树初始化失败").code(1999).success(false).build());
            }
            list = getListTree(orgList, pd);
            list = (List<PageData>) list.get(0).get("children");
            ListResult<PageData> Result = new ListResult<>(CommonCode.SUCCESS);
            Result.setList(list);
            Result.setTotal(list.size());
            return Result;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ListResult<>(CommonCode.ERROR);
        }
    }

    public List<PageData> getListTree(List<PageData> orgList, PageData pd) throws Exception {
        List<PageData> tree = new ArrayList<>();
        List<PageData> list = new ArrayList<>();
        for (PageData org : orgList) {
            List<PageData> orgChildren = (List<PageData>) org.get("children");
            List<PageData> parentList = new ArrayList<>();
//            if (CollectionUtil.isNotEmpty(orgChildren)) {
            switch (org.getString("typeCode")) {
                case "0":
                    if (Tools.isEmpty(pd.getString("reportTime"))) {
                        list = findlist(org.getString("id"), "", "6");
                    } else {
                        list = findlist(org.getString("id"), pd.getString("reportTime"), "6");
                    }
                    if (list.size() == 0) {
                        PageData pdd = new PageData();
                        pdd.put("orgName", org.getString("name"));
                        pdd.put("tableTypeCode", "6");
                        pdd.put("reportTime", pd.getString("reportTime"));
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        list.add(pdd);
                    }

                    for (PageData p : list) {
                        List<PageData> childList = new ArrayList<>();
                        //遍历当前单位的下属子企业
                        List<PageData> childs = new ArrayList<>();
                        childs = findlist(org.getString("id"), p.getString("reportTime"), "0");
                        if (childs.size() > 0) {
                            for (PageData child : childs) {
                                childList.add(child);
                            }
                        } else {
                            PageData pdd = new PageData();
                            pdd.put("orgName", org.getString("name"));
                            pdd.put("tableTypeCode", "0");
                            pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                            childList.add(pdd);
                        }
                        childList.addAll(getListTree(orgChildren, pd));
                        p.put("children", childList);
                    }
                    tree.addAll(list);
                    break;
                case "1":
                    list = findlist(org.getString("id"), pd.getString("reportTime"), "0");
                    if (list.size() == 0) {
                        PageData pdd = new PageData();
                        pdd.put("orgName", org.getString("name"));
                        pdd.put("tableTypeCode", "0");
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        list.add(pdd);
                    }
                    tree.addAll(list);
                    break;
                case "2":
                    list = findlist(org.getString("id"), pd.getString("reportTime"), "0");
                    if (list.size() == 0) {
                        PageData pdd = new PageData();
                        pdd.put("orgName", org.getString("name"));
                        pdd.put("tableTypeCode", "0");
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        list.add(pdd);
                    }
                    tree.addAll(list);
                    break;
                case "3":
                    orgzationService.getParentList(org.getString("parentId"), parentList);
                    int summaryCode = parentList.size();
                    pd.put("id", org.getString("id"));
                    pd.put("typeCode", 2);
                    List<PageData> typeOrgs = orgzationDao.findorgbyidandtype(pd);
                    List<PageData> delOrgs = new ArrayList<>();
                    for (PageData orgType : typeOrgs) {
                        for (PageData child : orgChildren) {
                            if (child.getString("id").equals(orgType.getString("id"))) {
                                delOrgs.add(child);
                            }
                        }
                    }
                    orgChildren.removeAll(delOrgs);
                    if (Tools.isEmpty(pd.getString("reportTime"))) {
                        list = findlist(org.getString("id"), "", "6", summaryCode - 1);
                    } else {
                        list = findlist(org.getString("id"), pd.getString("reportTime"), "6", summaryCode - 1);
                    }
                    if (list.size() == 0) {
                        PageData pdd = new PageData();
                        pdd.put("orgName", org.getString("name"));
                        pdd.put("tableTypeCode", "6");
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        list.add(pdd);
                    }
                    for (PageData p : list) {
                        List<PageData> childList = new ArrayList<>();
                        //遍历当前单位的下属子企业
                        List<PageData> childs = new ArrayList<>();
                        childs = findlist(org.getString("id"), pd.getString("reportTime"), "", summaryCode);
                        if (childs.size() > 0) {
                            for (PageData child : childs) {
                                if ("6".equals(child.getString("tableTypeCode"))) {
                                    List<PageData> summarySmall = findlist(org.getString("id"), pd.getString("reportTime"), "0", summaryCode + 1);
                                    for (PageData branch : typeOrgs) {
                                        List<PageData> branchOrgs = findlist(branch.getString("id"), pd.getString("reportTime"), "0", summaryCode + 1);
                                        if (branchOrgs.size() > 0) {
                                            summarySmall.addAll(branchOrgs);
                                        } else {
                                            PageData pdd = new PageData();
                                            pdd.put("orgName", branch.getString("name"));
                                            pdd.put("tableTypeCode", "0");
                                            pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                                            summarySmall.add(pdd);
                                        }

                                    }
                                    for (PageData branchpd : summarySmall) {
                                        if ("1".equals(branchpd.getString("tableTypeCode"))) {
                                            branchpd.put("isSmallSummary", 1);
                                        }
                                    }
                                    child.put("children", summarySmall);
                                    child.put("isSmallSummary", 1);
                                }
                                childList.add(child);
                            }
                        } else {
                            PageData pdd = new PageData();
                            pdd.put("orgName", org.getString("name"));
                            pdd.put("tableTypeCode", "6");
                            pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                            childList.add(pdd);
                        }
                        childList.addAll(getListTree(orgChildren, pd));
                        p.put("children", childList);
                    }
                    tree.addAll(list);
                    break;
                default:
                    break;
            }
        }
//        }
        return tree;
    }

    /**
     * 递归，建立树形结构
     *
     * @param pd
     * @return
     */
    public List<PageData> listTree(PageData pd) throws Exception {
        if (Tools.isEmpty(pd.getString("orgId"))) {
            pd.put("orgId", pd.getString("id"));
        }
        PageData orgpd = orgzationDao.findbyid(pd.getString("orgId"));
        List<PageData> parentList = new ArrayList<>();
        orgzationService.getParentList(orgpd.getString("parentId"), parentList);
        int summaryCode = parentList.size();
        List<PageData> list = new ArrayList<>();
        List<PageData> orgs = orgzationDao.findchildbyid(pd.getString("orgId"));
        switch (orgzationDao.findbyid(pd.getString("orgId")).getString("typeCode")) {
            case "0":
                if (orgs.size() > 1) {
                    if (Tools.isEmpty(pd.getString("reportTime"))) {
                        list = findlist(pd.getString("orgId"), "", "6");
                    } else {
                        list = findlist(pd.getString("orgId"), pd.getString("reportTime"), "6");
                    }
                    //遍历该企业填报的全面预算
                    for (PageData p : list) {
                        List<PageData> childList = new ArrayList<>();
                        //遍历当前单位的下属子企业
                        for (PageData org : orgs) {
                            List<PageData> childs = new ArrayList<>();
                            if (org.getString("id").equals(pd.getString("orgId"))) {
                                childs = findlist(org.getString("id"), p.getString("reportTime"), "0");
                                for (PageData child : childs) {
                                    childList.add(child);
                                }

                            } else {
                                List<PageData> orgchilds = orgzationService.getChlidList(org.getString("id"));
                                if (orgchilds.size() > 1) {
                                    childs = findlist(org.getString("id"), p.getString("reportTime"), "6");
                                } else {
                                    childs = findlist(org.getString("id"), p.getString("reportTime"), "0");
                                }
                                for (PageData child : childs) {
                                    org.put("reportTime", child.getString("reportTime"));
                                    if (orgchilds.size() > 1) {
                                        child.putAll(listTree(org).get(0));
                                    }
                                    childList.add(child);
                                }
                            }
                        }
                        p.put("children", childList);
                    }
                }
                break;
            case "1":
                list = findlist(pd.getString("orgId"), "", "0");
                break;
            case "2":
                list = findlist(pd.getString("orgId"), "", "0");
                break;
            case "3":
                pd.put("id", pd.getString("orgId"));
                pd.put("typeCode", "2");
                List<PageData> typeOrgs = orgzationDao.findorgbyidandtype(pd);
                if (Tools.isEmpty(pd.getString("reportTime"))) {
                    list = findlist(pd.getString("orgId"), "", "6", summaryCode - 1);
                } else {
                    list = findlist(pd.getString("orgId"), pd.getString("reportTime"), "6", summaryCode - 1);
                }

                //遍历该企业填报的全面预算
                for (PageData p : list) {
                    List<PageData> childList = new ArrayList<>();
                    //遍历当前单位的下属子企业
                    for (PageData org : orgs) {
                        List<PageData> childs = new ArrayList<>();
                        if (org.getString("id").equals(pd.getString("orgId"))) {
                            childs = findlist(org.getString("id"), p.getString("reportTime"), "", summaryCode);
                            for (PageData child : childs) {
                                if ("6".equals(child.getString("tableTypeCode"))) {
                                    List<PageData> summarySmall = findlist(org.getString("id"), p.getString("reportTime"), "0", summaryCode + 1);
                                    for (PageData branch : typeOrgs) {
                                        List<PageData> branchOrgs = findlist(branch.getString("id"), p.getString("reportTime"), "0", summaryCode + 1);
                                        summarySmall.addAll(branchOrgs);
                                    }
                                    for (PageData branchpd : summarySmall) {
                                        if ("1".equals(branchpd.getString("tableTypeCode"))) {
                                            branchpd.put("isSmallSummary", 1);
                                        }
                                    }
                                    child.put("children", summarySmall);
                                    child.put("isSmallSummary", 1);
                                }
                                childList.add(child);
                            }

                        } else {

                            List<PageData> orgchilds = orgzationService.getChlidList(org.getString("id"));
                            if (orgchilds.size() > 1) {
                                childs = findlist(org.getString("id"), p.getString("reportTime"), "6", summaryCode);
                            } else {
                                childs = findlist(org.getString("id"), p.getString("reportTime"), "0", summaryCode);
                            }
                            for (PageData child : childs) {
                                org.put("reportTime", child.getString("reportTime"));
                                if (orgchilds.size() > 1) {
                                    child.putAll(listTree(org).get(0));
                                }
                                childList.add(child);
                            }
                        }
                    }
                    p.put("children", childList);
                }
                break;
            default:
                break;
        }
        return list;
    }

    public List<PageData> findlist(String id, String reportTime, String type) throws Exception {
        return findlist(id, reportTime, type, 999);
    }

    /*
     * 列表界面查询
     *
     * */
    public List<PageData> findlist(String id, String reportTime, String type, int summaryCode) throws Exception {
        PageData pd = new PageData();
        pd.put("orgId", id);
        if (!Tools.isEmpty(reportTime)) {
            if (reportTime.length() < 10) {
                reportTime = reportTime + "-01";
            }
            pd.put("reportTime", reportTime);
        }
        if (type != null && "0".equals(type)) {
            type = "b.table_type_code != '6'";
            pd.put("formType", type);
        } else if (type != null && "6".equals(type)) {
            type = "b.table_type_code = '6'";
            pd.put("formType", type);
        }
        if (summaryCode != 999) {
            String summary = summaryCode + "";
            pd.put("summaryCode", summary);
        }
        List<PageData> valueList = bulletinDao.listByCondition(pd);
        return valueList;

    }

    /*
详情
*/
    public ObjResult detail(PageData pd) {
        ObjResult objResult;
        try {
            PageData pddetail;
            PageData pdlast = new PageData();
            String year;
            String month;
            if (Tools.isEmpty(pd.getString("orgId"))) {
                pd.put("orgId", TokenUtil.getTokenOrgId());
            }
            if (Tools.notEmpty(pd.getString("reportTime"))) {
                year = pd.getString("reportTime").substring(0, 4);
                month = pd.getString("reportTime").substring(5, 7);
                pd.put("reportTime", pd.getString("reportTime") + "-01");
                pddetail = bulletinDao.findByDate(pd);
            } else {
                pddetail = bulletinDao.findById(pd);
                year = pddetail.getString("reportTime").substring(0, 4);
                month = pddetail.getString("reportTime").substring(5, 7);
                pd.put("reportTime", pddetail.getString("reportTime"));
            }

            pd.put("startTime", year + "-01-01");
//            pdlast.put("reportTime", (Integer.parseInt(year) - 1) + "-" + month + "-01");
//            pdlast.put("orgId", pddetail.getString("orgId"));
//            PageData pdsum = bulletinDao.findSumByDate(pd);
//            pdlast = bulletinDao.findByDate(pdlast);
            pd.put("pddetail", pddetail);
            pd.put("orgId", pddetail.getString("orgId"));
//            pd.put("pdsum", pdsum);
//            pd.put("pdlast", pdlast);
            String tableTypeCode = pddetail.getString("tableTypeCode");
            String tableTypeName = "";
            if ("0".equals(tableTypeCode)){
                tableTypeName = "（单户）";
            }else if ("1".equals(tableTypeCode)){
                tableTypeName = "（差额）";
            }else if ("6".equals(tableTypeCode)){
                tableTypeName = "（合并）";
            }
            pddetail.put("orgName", pddetail.getString("orgName") + tableTypeName);
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(pd);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
            return objResult;
        }
        return objResult;
    }
    public PageData getDefaultTime() throws Exception{
        return getDefaultTime(new PageData());
    }
    public PageData getDefaultTime(PageData pageData) throws Exception {
        PageData pd = new PageData();
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM");

            String nowStr = DateUtil.format(DateUtil.now(), DateUtil.PATTERN_MONTH);
            List<PageData> unitOrgList = new ArrayList<>();
            if (orgService.getDTFlag(nowStr)){
                unitOrgList = orgzationDao.findGZWUnitsFilterDT();
            }else {
                unitOrgList = orgzationDao.findGZWUnits();
            }
            if (CollectionUtil.isEmpty(unitOrgList)){
                pd.put("reportTime", nowStr);
                return pd;
            }

            List<String> unitList = unitOrgList.stream().map(unit -> unit.getString("id")).collect(Collectors.toList());
            String[] units = unitList.toArray(new String[unitList.size()]);
            pd.put("orgList", units);
            PageData defaultTime = new PageData();
            if (Tools.isEmpty(pageData.getString("reportTime"))){
                defaultTime = bulletinDao.getDefaultTime(pd);
            }else {
                pageData.put("orgList", units);
                defaultTime.put("reportTime", pageData.getString("reportTime"));
                PageData count = bulletinDao.getCountByDate(pageData);
                if (count == null){
                    count = new PageData();
                }
                if (Tools.isEmpty(count.getString("dateCount"))){
                    defaultTime.put("dateCount", 0);
                }else {
                    defaultTime.put("dateCount", count.getString("dateCount"));
                }

            }
            Calendar calendar = Calendar.getInstance();
            int nowYear = calendar.get(Calendar.YEAR);
            if (defaultTime != null) {
                Date date = df.parse(defaultTime.getString("reportTime"));
                calendar.setTime(date);
                if (defaultTime.getInteger("dateCount") < (units.length - 1)) {
                    PageData p = new PageData();
                    calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
                    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
                    int year = calendar.get(Calendar.YEAR);
                    if (nowYear - year > 2){
                        pd.put("reportTime", DateUtil.format(DateUtil.now(), DateUtil.PATTERN_MONTH));
                        return pd;
                    }
                    p.put("reportTime",df.format(calendar.getTime()));
                    PageData time = getDefaultTime(p);
                    Date date1 = df2.parse(time.getString("reportTime"));
                    calendar.setTime(date1);
                } else {
                    calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
                    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
                }
            }else {
                PageData p = new PageData();
                calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
                calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
                p.put("reportTime",df.format(calendar.getTime()));
                PageData time = getDefaultTime(p);
                Date date = df2.parse(time.getString("reportTime"));
                calendar.setTime(date);
            }


            pd.put("reportTime", df2.format(calendar.getTime()));
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw e;
        }
        return pd;
    }

    /**
     * 导入报表
     *
     * @param
     * @throws Exception
     */
    public ObjResult uploadFile(MultipartHttpServletRequest request) {
        ObjResult objResult;
        UploadUtil uploadUtil = new UploadUtil();
        PageData pddetail = new PageData();
        PageData pdsum = new PageData();
        PageData pdlast = new PageData();
        String sql[] = {
                "YYZSLR", "YYCB", "SJJFJ", "XSFY", "GLFY", "YFFY", "CWFY", "LXZC", "HDJSS", "ZCJZSS",
                "QTSY", "TZSY", "DLYQYHHYQYDTZSY", "GYJZBDSY", "ZCCZSY", "YYLR", "YYWSZJE", "ZFBZ",
                "LRZE", "JLR", "GSYMGSSYZDJLR", "ZCZE", "LDZC", "HBZJ", "YSPJJYSZK", "YSZK", "STORAGE",
                "YCL", "KCSP", "FZZE", "LDFZ", "YFPJJYFZK", "DXFZZE", "YHJK", "YFZQ", "SYZQYZE", "GSYMGSDSYZQYZE",
                "JYHDCSDXJLLJE", "ZBHLXZC", "YJSFZE", "YIJSFZE", "ZGXC", "ZGGZZE", "ZGZGGZZG", "ZGRS", "ZGZGRS",
                "GDZCTZE", "JTZJE", "LDSCZZ", "GYZCZ", "GYXSCZ", "CKCPXSSR", "XCPCZ"
        };
        try {
//            按表格的标签名称导入
            PageData pd = new PageData(request);
            PageData p = new PageData();
            MultipartFile mp = request.getFile("file");
            if (mp != null) {
                InputStream stream = mp.getInputStream();
                //接收文件流
                //将流给工作簿
                Workbook book = null;
                if ("application/vnd.ms-excel".equals(mp.getContentType())) {
                    book = new HSSFWorkbook(stream);
                } else {
                    book = new XSSFWorkbook(stream);
                }
                //遍历sheet
                List<PageData> list = new ArrayList<>();
                Sheet sheet = book.getSheetAt(0);
                String sheetname = sheet.getSheetName();

                //遍历行
                for (int rowNum = 4; rowNum < 57; rowNum++) {
                    Row row = sheet.getRow(rowNum);
                    PageData pd_row = new PageData();
                    if (null == row) {
                        continue;
                    }
                    PageData p2 = new PageData();
                    //遍历列
                    for (int cellNum = 2; cellNum <= row.getLastCellNum(); cellNum++) {

                        Cell cell = row.getCell(cellNum);
                        if (null == cell) {
                            continue;
                        }
                        Cell cell1 = row.getCell(cellNum + 1);
                        switch (cellNum) {
                            case 2:
                                if ((24 < rowNum && rowNum < 41) || (47 < rowNum && rowNum < 50)) {
                                    pddetail.put(sql[rowNum - 4], uploadUtil.getCellValue(cell1));
                                } else {
                                    pddetail.put(sql[rowNum - 4], uploadUtil.getCellValue(cell));
                                }
                                break;
                            case 3:
                                if ((24 < rowNum && rowNum < 41) || (47 < rowNum && rowNum < 50)) {
                                    pdsum.put("SUM_" + sql[rowNum - 4], null);
                                } else {
                                    pdsum.put("SUM_" + sql[rowNum - 4], uploadUtil.getCellValue(cell));
                                }
                                break;
                            case 4:
                                pdlast.put("LAST_" + sql[rowNum - 4], uploadUtil.getCellValue(cell));
                                break;
                            default:
                                break;
                        }
                    }
                }
                Row row = sheet.getRow(57);

                for (int cellNum = 0; cellNum <= row.getLastCellNum(); cellNum++) {
                    Cell cell = row.getCell(cellNum);
                    if (uploadUtil.getCellValue(cell).contains("填表人：")) {
                        pd.put("applicant", uploadUtil.getCellValue(cell).substring(4, uploadUtil.getCellValue(cell).toString().length()));
                    } else if (uploadUtil.getCellValue(cell).contains("联系电话：")) {
                        pd.put("phone", uploadUtil.getCellValue(cell).substring(5, uploadUtil.getCellValue(cell).toString().length()));
                    }
                }
                pd.put("pddetail", pddetail);
                pd.put("pdsum", pdsum);
                pd.put("pdlast", pdlast);
                book.close();
                stream.close();
            }
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(pd);

        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
        }
        return objResult;
    }

    /**
     * 导出报表
     *
     * @param
     * @throws Exception
     */
    public void exportExcel(PageData pd, HttpServletResponse response, OutputStream os) throws Exception {
//
//        PageData pd = new PageData(request);
        String fname = "财务快报";
        os = response.getOutputStream();//取得输出流
        response.reset();//清空输出流
        //下面是对中文文件名的处理
        response.setCharacterEncoding("UTF-8");//设置相应内容的编码格式
        //读取系统中的模板
        InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/邢台市财务快报模板.xlsx");
        fname = java.net.URLEncoder.encode(fname, "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(fname.getBytes("UTF-8"), "UTF-8") + ".xls");

        response.setContentType("application/msexcel");//定义输出类型

        HashMap thisMonth = (HashMap) pd.get("thisMonth");
        HashMap thisYear = (HashMap) pd.get("thisYear");
        HashMap lastYear = (HashMap) pd.get("lastYear");
        PageData tm = new PageData();
        PageData ty = new PageData();
        PageData ly = new PageData();

        List<String> rows = (List<String>) pd.get("rowList");
        for (Object key : thisMonth.keySet()) {
            tm.put(key.toString(), thisMonth.get(key));
        }
        for (Object key : thisYear.keySet()) {
            ty.put(key.toString(), thisYear.get(key));
        }
        for (Object key : lastYear.keySet()) {
            ly.put(key.toString(), lastYear.get(key));
        }
//        克隆模板得到一个新的excel模板
        DynamicOperateExcelUtils dynamicOperateExcelUtils = new DynamicOperateExcelUtils(inputStream);
//        获取工作簿
        Workbook workbook = dynamicOperateExcelUtils.getWorkbook();
//            获取表格
        Sheet sheet = dynamicOperateExcelUtils.getSheet(0);
//            插入数据
        for (int a = 0; a < tm.size(); a++) {
//                    非增行的替换模板单元格的数据
            for (int b = 0; b < 3; b++) {
                switch (b) {
                    case 0:
                        dynamicOperateExcelUtils.replaceCellValue(a + 4, b + 2, tm.getString(rows.get(a)));
                        break;
                    case 1:
                        dynamicOperateExcelUtils.replaceCellValue(a + 4, b + 2, ty.getString(rows.get(a)));
                        break;
                    case 2:
                        dynamicOperateExcelUtils.replaceCellValue(a + 4, b + 2, ly.getString(rows.get(a)));
                        break;
                    default:
                        break;

                }

            }
        }
        dynamicOperateExcelUtils.replaceCellValue(tm.size() + 4, 0, "填表人：" + (pd.getString("applicant") == null ? "" : pd.getString("applicant")));
        dynamicOperateExcelUtils.replaceCellValue(tm.size() + 4, 1, "联系电话：" + (pd.getString("phone") == null ? "" : pd.getString("phone")));


//        dynamicOperateExcelUtils.exportExcel("D:/excel2.xlsx");
        workbook.write(os);
        os.flush();
        os.close();
        workbook.close();
    }


    /**
     * 提交单据
     *
     * @param formId 单据id
     */
    public HashMap<String, Object> commit(String formId){
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(FLOW));
        ArrayList<String> ids = new ArrayList<>();
        ids.add(formId);
        pageData.put("id", ids);
        try {
            bulletinDao.refer(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException("提交失败");
        }
        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<>();
    }

    /**
     * 退回单据
     *
     * @param formId 单据id
     */
    public Boolean reject(String formId, int formState, String comment){
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(formState));
        pageData.put("id", Collections.singletonList(formId));
        try {
            bulletinDao.refer(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new RuntimeException(e);
        }
        return true;
    }

    public Boolean finish(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(FINISH));
            pageData.put("id", Collections.singletonList(formId));
            bulletinDao.refer(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("单据流转完成时修改单据状态失败！"));
        }
        return true;
    }

    /**
     * @param formIds 单据ids
     */
    public List<PageData> findByIds(List<String> formIds) {
        try {
            PageData pageData = new PageData();
            pageData.put("ids", formIds);
            List<PageData> byIds = bulletinDao.findByIds(pageData);
            List<PageData> pageData1 = new ArrayList<>();
            for (PageData pd:byIds){
                String unitname = pd.getString("UNITNAME");
                pd.put("orgName",unitname);
                pageData1.add(pd);
            }
            //UNITNAME
            return pageData1;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("根据单据id列表查询报表失败！"));
        }
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(FR_BULLETIN);
    }

    public void goBackToStash(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(UNREVIEWED));
            pageData.put("id", Collections.singletonList(formId));
            bulletinDao.refer(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
    }

    public ObjResult childList(PageData pd) throws Exception{
        String orgId = pd.getString("orgId");
        List<PageData> children = orgzationDao.findchildbyid(orgId);
        if (CollectionUtil.isEmpty(children)){
            throw new MyRuntimeException(new ObjResult("获取下级单位失败！"));
        }
        pd.put("orgIds", children.stream().map(p -> p.getString("id")).collect(Collectors.toList()));
        List<PageData> bulletinList = bulletinDao.summaryChildList(pd);

        if (CollectionUtil.isNotEmpty(bulletinList)){
            bulletinList = bulletinList.stream().filter(p ->
                    !(orgId.equals(p.getString("orgId")) && "6".equals(p.getString("tableTypeCode")))).collect(Collectors.toList());
        }
        PageData pageData = new PageData();
        pageData.put("childList", bulletinList);
//        bulletinSummaryRelationService.submit("b905bbaaf0374d018b3211fd36796e6d", bulletinList.stream().map(p -> p.getString("id")).collect(Collectors.toList()));
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        objResult.setPageData(pageData);
        return objResult;
    }

    public ObjResult childSummary(PageData pd) throws Exception{
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        objResult.setPageData(bulletinDao.summaryByIds(pd));
        return objResult;
    }

    public ObjResult getSummaryDetail(PageData pd) throws Exception{
        List<PageData> childList = bulletinDao.getSummaryDetail(pd);
        String columnName = pd.getString("columnName");
        List<BulletinSummaryDetailVO> summaryDetailVOS = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(childList)){
            summaryDetailVOS = childList.stream().map(child -> BulletinSummaryDetailVO.builder()
                    .bulletinId(pd.getString("id")).childBulletinId(child.getString("id")).orgId(child.getString("orgId"))
                    .orgName(child.getString("orgName")).tableTypeCode(child.getString("tableTypeCode"))
                    .detailAmount(new BigDecimal(StringUtil.isBlank(child.getString(columnName)) ? "0" : child.getString(columnName))).build())
                    .collect(Collectors.toList());
        }
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        PageData result = new PageData();
        result.put("details", summaryDetailVOS);
        objResult.setPageData(result);
        return objResult;
    }
}

